<template>
  <div>
    <!-- 面包屑导航 -->
    <bread-crumb :breadPath="breadPath"></bread-crumb>
    <!-- 卡片视图区 -->
    <el-card class="box-card">
      <!-- 警告提示区 -->
      <el-row>
        <el-col :span="12" :push="1">
          <el-alert show-icon title="注意：只允许为第三级分类设置相关参数！" type="warning" :closable="false"></el-alert>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12" :push="1">
          <el-alert show-icon title="注意：参数的选项Tag标签不可输入带空格的数据！" type="warning" :closable="false"></el-alert>
        </el-col>
      </el-row>
      <!-- 选择商品分类区 -->
      <el-row class="cate-option">
        <el-col>
          <span>选择商品分类：</span>
          <!-- 级联选择器 options用于指定数据源 -->
          <!-- props 用于指定配置对象 -->
          <el-cascader v-model="selectedKeys" :options="cateList" :show-all-levels="false"
                      :props="cascaderProps" @change="parentCateChanged" clearable>
          </el-cascader>
        </el-col>
      </el-row>
      <!-- Tabs分页标签区 切换不同类型的商品参数 -->
      <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
        <!-- 动态参数面板Tab -->
        <el-tab-pane label="动态参数" name="many">
          <!-- 添加动态参数的按钮 -->
          <el-button type="primary" size="mini" :disabled="isChoise" @click="addDialogVisible = true">添加参数</el-button>
          <!-- 动态参数 数据表格 -->
          <el-table :data="manyTableData" border stripe>
            <!-- 展开列 -->
            <el-table-column type="expand">
              <template v-slot:default={row}>
                <!-- 循环渲染Tag标签 动态参数的选项标签 -->
                <el-tag v-for="(item, i) in row.attr_vals" :key="i" closable @close="handleClose(i, row)">{{item}}</el-tag>
                <!-- 输入框 点击按钮切换成输入框 -->
                <el-input class="input-new-tag" v-if="row.inputVisible" v-model="row.inputValue"
                          ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm(row)" @blur="handleInputConfirm(row)">
                </el-input>
                <!-- 按钮 输入框隐藏时显示 -->
                <el-button v-else class="button-new-tag" size="small" @click="showInput(row)">+ New Tag</el-button>
              </template>
            </el-table-column>
            <!-- 索引列 -->
            <el-table-column label="#" type="index"></el-table-column>
            <!-- 数据列 -->
            <el-table-column label="参数名称" prop="attr_name"></el-table-column>
            <!-- 操作列 -->
            <el-table-column label="操作" width="300px">
              <template v-slot:default={row}>
                <!-- v-slot:default="scope" -->
                <!-- 编辑按钮 -->
                <el-button type="primary" icon="el-icon-edit" size="mini" @click="showEditDialog(row)">编辑</el-button>
                <!-- 删除按钮 -->
                <el-button type="danger" icon="el-icon-delete" size="mini" @click="removeParamById(row.attr_id)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
        <!-- 静态属性面板Tab -->
        <el-tab-pane label="静态属性" name="only">
          <!-- 添加静态属性的按钮 -->
          <el-button type="success" size="mini" :disabled="isChoise" @click="addDialogVisible = true">添加属性</el-button>
          <!-- 静态属性 数据表格 -->
          <el-table :data="onlyTableData" border stripe>
            <!-- 展开列 -->
            <el-table-column type="expand">
              <template v-slot:default={row}>
                <!-- 循环渲染Tag标签 静态属性的选项标签 -->
                <el-tag v-for="(item, i) in row.attr_vals" :key="i" closable @close="handleClose(i, row)">{{item}}</el-tag>
                <!-- 输入框 点击按钮切换成输入框 -->
                <el-input class="input-new-tag" v-if="row.inputVisible" v-model="row.inputValue"
                          ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm(row)" @blur="handleInputConfirm(row)">
                </el-input>
                <!-- 按钮 输入框隐藏时显示 -->
                <el-button v-else class="button-new-tag" size="small" @click="showInput(row)">+ New Tag</el-button>
              </template>
            </el-table-column>
            <!-- 索引列 -->
            <el-table-column label="#" type="index"></el-table-column>
            <!-- 数据列 -->
            <el-table-column label="属性名称" prop="attr_name"></el-table-column>
            <!-- 操作列 -->
            <el-table-column label="操作" width="300px">
              <template v-slot:default={row}>
                <!-- v-slot:default="scope" -->
                <!-- 编辑按钮 -->
                <el-button type="primary" icon="el-icon-edit" size="mini" @click="showEditDialog(row)">编辑</el-button>
                <!-- 删除按钮 -->
                <el-button type="danger" icon="el-icon-delete" size="mini" @click="removeParamById(row.attr_id)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>
    </el-card>
    <!-- 添加 参数/属性 对话框 -->
    <el-dialog :title="'添加'+addText" :visible.sync="addDialogVisible" width="50%" @close="addDialogClosed">
      <!-- 内容主体区 -->
      <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="80px">
        <el-form-item :label="addText" prop="attr_name">
          <el-input v-model="addForm.attr_name"></el-input>
        </el-form-item>
      </el-form>
      <!-- 底部区 -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addParams">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 编辑 参数/属性 对话框 -->
    <el-dialog :title="'编辑'+addText" :visible.sync="editDialogVisible" width="50%" @close="editDialogClosed">
      <!-- 内容主体区 -->
      <el-form :model="editForm" :rules="addFormRules" ref="editFormRef" label-width="80px">
        <el-form-item :label="addText" prop="attr_name">
          <el-input v-model="editForm.attr_name"></el-input>
        </el-form-item>
      </el-form>
      <!-- 底部区 -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="editDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="editParams">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
  import breadCrumb from '@/components/breadcrumb'
  import { getCategories, getParamsById, postAddParams, putEditParams, deleteParam } from '@/api/goods.js';

  export default {
    data() {
      return {
        // 面包屑导航 数据
        breadPath: ['商品管理', this.$route.query.bread],
        // 商品分类列表 级联选择器 数据
        cateList: [],
        // 级联选择器的数据对象 用于配置级联选择器选项的表现效果
        cascaderProps: {
          expandTrigger: 'hover',
          value: 'cat_id',
          label: 'cat_name',
          children: 'children'
        },
        // 级联选择器 当前选中的 分类id 因分有多级，所以类型是一个数组。
        selectedKeys: [],
        // tabs标签 当前选中选项对应的name值
        activeName: 'many',
        // 动态参数 数据列表
        manyTableData: [],
        // 静态属性 数据列表
        onlyTableData: [],
        // 控制添加表单的显示和隐藏
        addDialogVisible: false,
        // 控制修改表单的显示和隐藏
        editDialogVisible: false,
        // 添加表单的 选项数据
        addForm: {
          attr_name: ''
        },
        // 修改表单的 选项数据
        editForm: {
          attr_name: '',
          attr_id: null
        },
        // 添加表单的 验证规则
        addFormRules: {
          attr_name: [
            { required: true, message: '请输入', trigger: 'blur' },
            { min: 2, max: 12, message: '长度在 2 到 12 个字符', trigger: 'blur' }
          ]
        },
      }
    },
    computed: {
      // 添加按钮的 禁用属性 如果没有选分类 则禁用按钮
      isChoise : function () {
        if ( this.selectedKeys.length == 3 ) {
          return false;
        }
        return true;
      },
      // 取选中分类 id数组的 第三级分类id
      cateId() {
        if ( this.selectedKeys.length === 3 ) {
          return this.selectedKeys[2]
        }
        return null;
      },
      // 根据tab选项的value 返回对应文字值
      addText() {
        if ( this.activeName === 'many' ) {
          return '动态参数'
        }
        return '静态属性';
      }
    },
    created() {
      this.getCateList();
    },
    methods: {
      // 获取商品分类列表数据 for级联选择器
      async getCateList() {
        await getCategories({ type: 3 })
          .then((res) => {
            this.cateList = res.data;
            // console.log(this.cateList);
          }).catch(err => err);
      },
      // 当级联选择器 变更选项时 触发的钩子函数
      parentCateChanged(value) {
        // 如果选择的不是第三级，则不会在selectedKeys中存储对应的分类ID
        if ( value.length != 3 && value.length != 0 ) {
          this.selectedKeys = [];
          this.manyTableData = [];
          this.onlyTableData = [];
          return this.$message.error('该分类不是三级分类！');
        }
        this.selectedKeys = value;
        // 判断一下是否选择了分类 因点击删除分类也会触发钩子函数 那时分类为空 不用查询对应参数
        if ( value.length == 0 ) {
          // 将之前的表格数据清空
          this.manyTableData = [];
          this.onlyTableData = [];
          return;
        }
        // 调用获取参数函数
        this.getParams();
      },
      // 点击 更改tabs标签页时 触发的钩子函数
      handleClick() {
        // 判断一下是否选择了分类 因点击删除分类也会触发钩子函数 那时分类为空 不用查询对应参数
        if ( this.selectedKeys.length == 0 ) return;
        // 调用获取参数函数
        this.getParams();
      },
      // 根据分类ID 获取对应参数
      getParams() {
        getParamsById(this.cateId, this.activeName)
          .then((res) => {
            res.data.forEach(element => {
              // 将分类的动态参数 由字符串拆分成数组
              element.attr_vals = element.attr_vals ? element.attr_vals.split(' ') : [];
              // 给每一个动态参数添加两个值 分别用来存储输入框的控制选项 和 输入内容绑定
                // 控制 Tag标签栏的 输入框和按钮的切换显示
              element.inputVisible = false;
                // 输入框的绑定数据
              element.inputValue = ''
            });
            // console.log(res);
            if ( this.activeName == 'many' ) {
              this.manyTableData = res.data;
              // console.log(this.manyTableData);
              return ;
            }
            this.onlyTableData = res.data;
            // console.log(this.onlyTableData);
          }).catch(() => {this.$message.error('操作失败！')});
      },
      // 添加表单 关闭时 重置表单 
      addDialogClosed() {
        this.$refs.addFormRef.resetFields();
      },
      // 添加新的动态参数/静态属性
      async addParams() {
        this.$refs.addFormRef.validate((valid) => {
          if (!valid) { return ; }
          let data = {
            attr_name: this.addForm.attr_name,
            attr_sel: this.activeName
          }
          postAddParams(this.cateId, data)
            .then(()=>{
              this.getParams();
              this.addDialogVisible = false;
              this.$message({ message: '添加成功！', type: 'success' });
            })
            .catch(() => {this.$message.error('操作失败！')})
        })
      },
      // 显示编辑对话框 查找对应分类的参数数据
      showEditDialog(attrData) {
        this.editForm.attr_name = attrData.attr_name;
        this.editForm.attr_id = attrData.attr_id;
        this.editDialogVisible = true;
      },
      // 编辑表单 关闭时 重置表单 
      editDialogClosed() {
        this.$refs.editFormRef.resetFields();
      },
      // 编辑动态参数/静态属性
      async editParams() {
        this.$refs.editFormRef.validate((valid) => {
          if (!valid) { return ; }
          let data = {
            id: this.cateId,
            attr_id: this.editForm.attr_id,
            attr_name: this.editForm.attr_name,
            attr_sel: this.activeName,
          }
          putEditParams(data)
            .then(()=>{
              this.$message({ message: '修改成功！', type: 'success' });
              this.getParams();
              this.editDialogVisible = false;
            })
            .catch(() => {this.$message.error('操作失败！')})
        })
      },
      // 删除 参数/属性
      async removeParamById(attrId) {
        const confirmResult = await this.$confirm(
          '此操作将永久删除该'+this.addText+', 是否继续?', '提示',
          { confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).catch(err => err);
        if (confirmResult !== 'confirm') {
          return this.$message.info('已取消删除');
        }
        // 调用删除的API请求接口
        deleteParam(this.cateId, attrId)
          .then(()=>{
            this.$message.success('已删除该'+this.addText);
            this.getParams();
          }).catch(() => {this.$message.error('操作失败！')})
      },
      // 更改一个动态参数对应的标签
      saveAttrVals(row) {
        let data = {
            id: row.cat_id,
            attr_id: row.attr_id,
            attr_name: row.attr_name,
            attr_sel: row.attr_sel,
            attr_vals: row.attr_vals.join(' ')
        }
        putEditParams(data)
          .then(()=>{
            console.log('success');
          })
          .catch(() => {this.$message.error('数据更新失败，请重新刷新页面')})
      },
      // input类型的Tag标签栏的输入框 回调函数，在按下enter键和失去焦点时调用
      handleInputConfirm(row) {
        // trim()去除字符串两端的空格，判断一下长度，如果为0，则为无效数据，置空返回
        let noSpaceValue = row.inputValue.trim();        
        if (noSpaceValue.length === 0) {
          row.inputValue = '';
          row.inputVisible = false;
          return ;
        }          
        // 不为空，再次判断数据中是否有空格
        if (noSpaceValue.indexOf(" ") != -1) {
          this.$message.error('请勿输入带空格的数据！');
          return ;
        }
        // 数据无空格，更新到前台data中
        row.attr_vals.push(noSpaceValue);
        row.inputValue = '';
        row.inputVisible = false;
        // 调用函数，将数据变更存入后台数据库
        this.saveAttrVals(row);
      },
      // input类型的Tag标签栏的新增按钮 回调函数 点击按钮后触发
      showInput(row) {
        row.inputVisible = true;
        // 自动获取焦点 
          // $nextTick 方法的作用：当页面上的元素 重新渲染之后，才会执行回调函数中的代码
        this.$nextTick(() => {
          this.$refs.saveTagInput.$refs.input.focus();
        });
      },
      // 删除标签 点击动态参数标签的删除按钮 触发该函数
      handleClose(i, row) {
        console.log(row);
        row.attr_vals.splice(i, 1);
        this.saveAttrVals(row);
      }
    },
    components: {
      breadCrumb
    }
  }
</script>

<style lang="less" scoped>
.cate-option {
  margin: 15px 0;
}
.el-button {
  margin-left: 5px;
}
.el-tag {
  margin: 8px;
}
// Tag 输入框
.input-new-tag {
  width: 120px;
}
// element Layout布局样式
.el-row {
    margin-bottom: 5px;
    &:last-child {
      margin-bottom: 0;
    }
  }
</style>